/*
Copyright (c) 2023 China Mobile Information Technology Co., Ltd
OpenGauss Operator is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/

package util

import (
	"errors"
	"fmt"
	"io/ioutil"
	v1 "k8s.io/api/core/v1"
	metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/klog/v2"
	"net"
	gsv1 "openGauss-operator/api/v1"
	"reflect"
	"strconv"
	"strings"
)

func MakeOwnerRef(gs *gsv1.OpenGaussCluster) []metaV1.OwnerReference {
	return []metaV1.OwnerReference{
		{
			APIVersion: gs.TypeMeta.APIVersion,
			Kind:       gs.TypeMeta.Kind,
			Name:       gs.ObjectMeta.Name,
			UID:        gs.ObjectMeta.UID,
		},
	}
}

func MakeBrOwnerRef(br *gsv1.OpenGaussBackupRecovery) []metaV1.OwnerReference {
	return []metaV1.OwnerReference{
		{
			APIVersion: br.TypeMeta.APIVersion,
			Kind:       br.TypeMeta.Kind,
			Name:       br.ObjectMeta.Name,
			UID:        br.ObjectMeta.UID,
		},
	}
}

func SetOneEnv(key string, value string) v1.EnvVar {
	return v1.EnvVar{
		Name:  key,
		Value: value,
	}
}

func GetNamespacedName(namespace, name string) types.NamespacedName {
	return types.NamespacedName{
		Namespace: namespace,
		Name:      name,
	}
}

func GetPodOrdinal(podName string) (int, error) {
	if podName == "" {
		return -1, nil
	}
	ordinal, err := strconv.Atoi(podName[(len(podName) - 1):])
	if err != nil {
		return ordinal, err
	}
	return ordinal, nil
}

func IsEmptyStruct(v interface{}) bool {
	t := reflect.TypeOf(v)
	if t.Kind() != reflect.Struct {
		return false
	}
	return reflect.DeepEqual(v, reflect.Zero(t).Interface())
}

func ParseIP(s string) (net.IP, int) {
	ip := net.ParseIP(s)
	if ip == nil {
		return nil, 0
	}
	for i := 0; i < len(s); i++ {
		switch s[i] {
		case '.':
			return ip, 4
		case ':':
			return ip, 6
		}
	}
	return nil, 0
}

func ReplaceData(commands []string, arg1 string) []string {
	for index := range commands {
		commands[index] = strings.Replace(commands[index], "${1}", arg1, -1)
	}
	return commands
}

func ReturnError(title string, err error) error {
	if err != nil {
		return errors.New(title + err.Error())
	}
	return errors.New(title)
}

func CheckPodNameFormat(gsName, podName string, dnNum int) (int, error) {

	ordinal, err := GetPodOrdinal(podName)
	if err != nil {
		return -1, err
	}

	if !strings.Contains(podName, gsName+"-") || len(podName) != len(gsName)+2 || ordinal < 0 || ordinal >= dnNum {
		return -1, errors.New("podName illegal format")
	}

	return ordinal, nil
}

func Command(command string) []string {
	return []string{commandStr1, commandStr2, command}
}

func ContainsStr(slice []string, s string) bool {
	for _, item := range slice {
		if item == s {
			return true
		}
	}
	return false
}

func RemoveStr(slice []string, s string) (result []string) {
	for _, item := range slice {
		if item == s {
			continue
		}
		result = append(result, item)
	}
	return result
}

func GetJobLabels(gs *gsv1.OpenGaussCluster, name string) map[string]string {
	return map[string]string{
		LabelOwnerCluster:  gs.Name,
		LabelMiddlewareKey: LabelMiddlewareValue,
		LabelJobName:       name,
	}
}

func IsCmsResource(resourceName string) bool {
	if strings.Contains(resourceName, CmsSuffixString) {
		return true
	}
	return false
}

func ReadFile(fileName string) (error, string) {
	context, err := ioutil.ReadFile(fileName)
	if err != nil {
		fmt.Println("Text.txt文件出错", err)
		klog.Errorf("Read %s err", fileName)
		return err, ""
	}
	return nil, string(context)
}
